package com.xyy.saas.payment.controller;

import com.alibaba.fastjson.JSON;
import com.xyy.ec.base.framework.rpc.ApiRPCResult;
import com.xyy.saas.payment.adpater.abchinaLoan.core.req.ApplyH5Dto;
import com.xyy.saas.payment.adpater.abchinaLoan.core.req.OrderStatusNotifyReq;
import com.xyy.saas.payment.adpater.abchinaLoan.core.req.QueryLoanDto;
import com.xyy.saas.payment.adpater.abchinaLoan.core.resp.QueryLoanStatusResp;
import com.xyy.saas.payment.adpater.abchinaLoan.service.AbchinaLoanService;
import com.xyy.saas.payment.callback.core.dto.CallbackMsg;
import com.xyy.saas.payment.callback.core.result.CallbackRunner;
import com.xyy.saas.payment.common.Builder;
import com.xyy.saas.payment.cores.constants.CallbackConstants;
import com.xyy.saas.payment.cores.enums.AbchinaLoanStatusEnum;
import com.xyy.saas.payment.cores.enums.FinanceChannelEnum;
import com.xyy.saas.payment.cores.enums.PinganLoanApplyStatusEnum;
import com.xyy.saas.payment.cores.vo.AbchinaLoanNotifyApplyStatusVo;
import com.xyy.saas.payment.cores.vo.ResultVO;
import com.xyy.saas.payment.dao.model.PayFinanceApply;
import com.xyy.saas.payment.service.PinganLoanFinanceApplyService;
import com.xyy.saas.payment.util.ABChinaUtil;
import com.xyy.saas.payment.util.RedisUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author wangzeqi
 */
@Slf4j
@RestController
@RequestMapping(value = {"/api/abchinaLoan/test"})
@AllArgsConstructor
public class AbchinaTestController {

    private final AbchinaLoanService abchinaLoanService;
    @Resource
    private CallbackRunner callbackRunner;
    @Resource
    private PinganLoanFinanceApplyService pinganLoanFinanceApplyService;
    @Autowired
    private RedisUtil redisUtil;

    @GetMapping("/redis/sMembers")
    public ResultVO<Set<String>> sMembers(String key) {
        Set<String> res = redisUtil.sMembers(key);
        return ResultVO.createSuccess(res);
    }

    @GetMapping("/redis/sRem")
    public ResultVO<Boolean> sRem(String key, String value) {
        boolean res = redisUtil.sRem(key, value);
        return ResultVO.createSuccess(res);
    }

    @GetMapping("/redis/sCard")
    public ResultVO<Long> sCard(String key) {
        Long res = redisUtil.sCard(key);
        return ResultVO.createSuccess(res);
    }

    @GetMapping("/redis/sAdd")
    public ResultVO<Boolean> sAdd(String key, String value) {
        redisUtil.sAdd(key, value);
        redisUtil.expire(key, 60, TimeUnit.SECONDS);
        return ResultVO.createSuccess(Boolean.TRUE);
    }

    @GetMapping("/redis/sIsmember")
    public ResultVO<Boolean> sIsmember(String key, String value) {
        boolean res = redisUtil.sIsmember(key, value);
        return ResultVO.createSuccess(res);
    }

    @GetMapping("/applyH5")
    public ResultVO<String> applyH5() {
        ApplyH5Dto applyH5Dto = ApplyH5Dto.mock();
        String url = abchinaLoanService.applyH5(applyH5Dto);
        return ResultVO.createSuccess(url);
    }

    @GetMapping("/queryLoanStatus")
    public ResultVO<QueryLoanStatusResp> queryLoanStatus() {
        QueryLoanDto queryLoanDto = QueryLoanDto.mock();
        QueryLoanStatusResp queryLoanStatusResp = abchinaLoanService.queryLoanStatus(queryLoanDto);
        return ResultVO.createSuccess(queryLoanStatusResp);
    }


    @PostMapping(value = "/notify/applyStatus/v1")
    public void notifyApplyStatus(AbchinaLoanNotifyApplyStatusVo abchinaLoanNotifyApplyStatusVo, HttpServletResponse response) {
        try {
            if (abchinaLoanNotifyApplyStatusVo == null || StringUtils.isBlank(abchinaLoanNotifyApplyStatusVo.getUscc()) ||
                    StringUtils.isBlank(abchinaLoanNotifyApplyStatusVo.getLoanStatus())) {
                log.error("参数为空");
                return;
            }
            final PinganLoanApplyStatusEnum applyStatusEnum = AbchinaLoanStatusEnum.getPinganLoanApplyStatusEnum(abchinaLoanNotifyApplyStatusVo.getLoanStatus());
            if (applyStatusEnum == null) {
                log.error("AbchinaLoanController notifyApplyStatus loanStatus inconsistent. param:{}", JSON.toJSONString(abchinaLoanNotifyApplyStatusVo));
                log.error("回调状态未知");
                return;
            }
            PayFinanceApply payFinanceApply = pinganLoanFinanceApplyService.findLatestRecordByLoanBalanceNo(abchinaLoanNotifyApplyStatusVo.getUscc(), FinanceChannelEnum.ABCHINA_LOAN.getCode());
            if (payFinanceApply == null) {
                log.error("外部企业统一信用代码在业务侧不存在");
                return;
            }
            payFinanceApply.setApplyStatus(applyStatusEnum.getCode());
            pinganLoanFinanceApplyService.updateByPrimaryKeySelective(payFinanceApply);
            // 回调ec
            abchinaLoanNotifyApplyStatusVo.setApplyStatus(applyStatusEnum);
            abchinaLoanNotifyApplyStatusVo.setUserId(payFinanceApply.getBusinessUserId());
            CallbackMsg callbackMsg = Builder.of(CallbackMsg::new)
                    .with(CallbackMsg::setCallback, CallbackConstants.ABCHINA_LOAN_CALLBACK_GROUP)
                    .with(CallbackMsg::setType, CallbackConstants.ABCHINA_LOAN_CALLBACK_APPLYSTATUS)
                    .with(CallbackMsg::setExtend, JSON.toJSONString(abchinaLoanNotifyApplyStatusVo))
                    .build();
            callbackRunner.callback(callbackMsg);

            log.info("成功");
        } catch (Exception e) {
            log.error("AbchinaLoanController notifyApplyStatus error:{}", e.getMessage(), e);
        }
    }

    @PostMapping(value = "/orderStatusNotify")
    public void orderStatusNotify(@RequestBody OrderStatusNotifyReq notifyReq) {
        try {

            Map<String, Object> respMap;
            if (!notifyReq.checkParam()) {
                respMap = buildFailedResponse("参数异常");
            } else {
                // todo 0-已推送总行（用户可放款）、1-受托支付成功、2-支付人取消订单
                ApiRPCResult apiRPCResult = abchinaLoanService.orderStatusNotify(notifyReq);
                if (apiRPCResult.isSuccess()) {
                    respMap = buildSuccessResponse(null);
                } else {
                    respMap = buildFailedResponse(apiRPCResult.getMsg());
                }
            }

            log.info("orderStatusNotify respMap:{}", JSON.toJSONString(respMap));

            // 加密
            // ABChinaUtil.encrypt(respMap, response);
        } catch (Exception e) {
            log.error("orderStatusNotify#error:{}", e.getMessage(), e);
        }
    }

    private Map<String, Object> buildSuccessResponse(Object data) {
        Map<String, Object> respMap = new HashMap<>(3);
        respMap.put("resCode", "0");
        respMap.put("resMsg", "成功");
        respMap.put("data", data);
        return respMap;
    }

    private Map<String, Object> buildFailedResponse(String errorMsg) {
        Map<String, Object> respMap = new HashMap<>(2);
        respMap.put("resCode", "-1");
        respMap.put("resMsg", errorMsg);
        return respMap;
    }

}
